package com.atguigu.gmall.order.service.impl;

import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.ribbon.apache.HttpClientUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @author: JC
 * @date: 2021/11/9 12:48
 */

@Service
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper,OrderInfo> implements OrderService {

    @Autowired
    private OrderInfoMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;

    @Value("${ware.url}")
    private String wareUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrderInfo(OrderInfo orderInfo) {
        // 1.orderInfo,orderDetail
        // 计算总金额
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        orderInfo.setOrderDetailList(orderDetailList);
        orderInfo.sumTotalAmount(); // 自动赋值
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());

        // 在控制器中赋值userId

        // 第三方交易编号 要求唯一
        String outTradeNo =  "ATGUIGU" + System.currentTimeMillis() + "" + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);

        // 订单描述
        orderInfo.setTradeBody("有钱就是玩！");
        orderInfo.setCreateTime(new Date());

        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,1);
        orderInfo.setExpireTime(instance.getTime());// 默认24小时过期

        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());// 进度状态

        orderMapper.insert(orderInfo);
        // 获取到订单明细
        orderDetailList.forEach(orderDetail -> {
            orderDetail.setOrderId(orderInfo.getUserId());
            orderDetailMapper.insert(orderDetail);
        });
        Long orderInfoId = orderInfo.getId();

        rabbitService.sendDelayMessage(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,MqConst.ROUTING_ORDER_CANCEL,orderInfoId,10);
        // 插入完数据 会有 订单id
        return orderInfoId;
    }

    @Override
    public String getTradeNo(String userId) {
        // 制作流水号
        String tradeNo = UUID.randomUUID().toString();
        // 存储到缓存中
        String tradeNoKey = "user:" + userId + ":tradeCode";
        redisTemplate.opsForValue().set(tradeNoKey, tradeNo,1, TimeUnit.DAYS);
        // 返回
        return tradeNo;
    }

    @Override
    public Boolean checkedTradeNo(String tradeNo, String userId) {
        String tradeNoKey = "user:" + userId + ":tradeCode";
        String tradeNoCache =(String) redisTemplate.opsForValue().get(tradeNoKey);

        return StringUtils.equals(tradeNo, tradeNoCache);
    }

    @Override
    public Boolean deleteTradeNo(String userId) {
        String tradeNoKey = "user:" + userId + ":tradeCode";
        return redisTemplate.delete(tradeNoKey);
    }

    @Override
    public boolean checkStock(Long skuId, Integer skuNum) {

        String result = HttpClientUtil.doGet(wareUrl + "/hasStock?skuId="+skuId+"&num="+skuNum);
        // 0: 无库存 1：有库存

        return "1".equals(result);
    }

    @Override
    public void execExpiredOrder(Long orderId) {
        // orderInfo
        updateOrderStatus(orderId, ProcessStatus.CLOSED);

        // 发送一个消息关闭交易记录

    }

    @Override
    public void updateOrderStatus(Long orderId, ProcessStatus processStatus) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderId);
        orderInfo.setProcessStatus(processStatus.name());
        orderInfo.setOrderStatus(processStatus.getOrderStatus().name());
        orderMapper.updateById(orderInfo);
    }

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        OrderInfo orderInfo = orderMapper.selectById(orderId);
        QueryWrapper<OrderDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderId);
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(queryWrapper);

        if(orderInfo != null){
            orderInfo.setOrderDetailList(orderDetailList);
        }

        return orderInfo;
    }

    @Override
    public void updateWareOrderStatus(Long orderId) {

        OrderInfo orderInfo = getOrderInfo(orderId);
        Gson gson = new Gson();
        String orderInfoJson = gson.toJson(orderInfo);

        rabbitService.sendDelayMessage(MqConst.EXCHANGE_DIRECT_WARE_STOCK,MqConst.ROUTING_WARE_STOCK,orderInfoJson,100);

    }


}
